import axios from "@/axios/axios"

import MUTATIONS from './mutations'
import {getSession, setSession} from "@/util/session"
import {formatTime, shuffle} from "@/util/function"

const {Notification} = ELEMENT;

const state = () => {
  return {
    topic: getSession('topic') || [],
    answerTime: parseInt(getSession('answerTime')) || 0
  }
}

const getters = {
  getScoreInfo(state) {
    return (queBankId) => {
      if (!queBankId) {
        const {A_SCORE, JD_SCORE, H_SCORE} = state.curHistoryInfo
        return {
          total: A_SCORE,
          score: H_SCORE,
          remainder: JD_SCORE
        }
      }
      return state.topic.reduce((scoreInfo, item) => {
        const score = parseInt(item.score);
        scoreInfo.total += score
        if (item.uAnswer) {
          item.result === '1' && (scoreInfo.score += score)
          item.type === '2' && (scoreInfo.remainder += score)
        }
        return scoreInfo;
      }, {total: 0, score: 0, remainder: 0})
    }
  },
  getTime(state) {
    return (queBankId) => {
      return formatTime(queBankId ? state.answerTime : state.curHistoryInfo.TIME);
    }
  }
}

const mutations = {
  [MUTATIONS.SET_TOPIC](state, topic) {
    //添加题目
    state.topic = topic
    setSession('topic', state.topic)
  },
  [MUTATIONS.SET_TOPIC_ANSWER](state, {index, answer}) {
    //设置用户答案
    state.topic[index].uAnswer = answer
    setSession('topic', state.topic)
  },
  [MUTATIONS.SET_RIGHT_ANSWER](state, {index, rAnswer}) {
    state.topic[index].rAnswer = rAnswer
  },
  [MUTATIONS.EMPTY_TOPIC](state) {
    //清空做题信息
    state.topic = []
    state.answerTime = 0
    Object.keys(state).map(key => !/user/.test(key) && sessionStorage.removeItem(key))
    sessionStorage.removeItem('curTopicIndex')
  },
  [MUTATIONS.MARK_ANSWER](state, {index, result}) {
    //批改选项
    state.topic[index].result = result
    setSession('topic', state.topic)
  },
  [MUTATIONS.SET_ANSWER_TIME](state, time) {
    //用户计时
    state.answerTime = time
    setSession('answerTime', state.answerTime)
  },
}
const actions = {
  getTopic({commit}, ID) {
    commit(MUTATIONS.EMPTY_TOPIC);

    function separateData(topic) {
      const {OPTION_ID, CHOOSE, IS_TYPE} = topic
      const {TM_ID, TM, TM_IMG, TX_TYPE, IS_SOUND, SCORE} = topic;

      return {
        topic: {
          id: TM_ID,
          type: TX_TYPE,
          title: TM,
          pic: TM_IMG,
          isSound: IS_SOUND,
          score: SCORE
        },
        option: {
          id: OPTION_ID,
          content: CHOOSE,
          type: IS_TYPE
        }
      };
    }

    return new Promise((resolve, reject) => {
      axios.post("question", {ID}).then((res) => {
        let topic = res.reduce((list, item, index) => {
          const {topic, option} = separateData(item)
          const lastIndex = list.length - 1;
          const listLastOption = lastIndex > -1 && list[lastIndex].option;
          const queNum = lastIndex + 2;
          const uAnswer = /[024]/.test(topic.type) ? '' : [];
          const rAnswer = ''
          if (/[24]/.test(topic.type)) {
            list.push({...topic, queNum, uAnswer, rAnswer})
          } else {
            if (!index || list[lastIndex].id !== item.TM_ID) {
              listLastOption && (list[lastIndex].option = shuffle(list[lastIndex].option))
              list.push({
                ...topic,
                queNum,
                option: [option],
                result: null,
                uAnswer,
                rAnswer
              })
            } else listLastOption.push(option)
          }
          return list;
        }, [])
        let lastTopicOption = topic[topic.length - 1].option;
        Array.isArray(lastTopicOption) && (topic[topic.length - 1].option = shuffle(lastTopicOption))
        commit(MUTATIONS.SET_TOPIC, topic)
        resolve()
      }).catch(reject)
    })
  },
  answerTopic({commit}, {index, answer}) {
    commit(MUTATIONS.SET_TOPIC_ANSWER, {index, answer})
  },
  markAnswer({commit, state, getters}, ID) {
    return new Promise(async (resolve, reject) => {
      //获取答案
      const res = await axios.post('answer.php', {ID}).catch(reject)
      const rAnswer = res.reduce((list, item) => {
        const {TM_ID: id, ANSWER_ID: answerId, ANSWER_VALUE: answerVal} = item;
        if (Object.keys(list).includes(id))
          list[id].push(answerId || answerVal)
        else list[id] = [answerId || answerVal]
        return list
      }, {})
      //批改答案
      for (let index = 0; index < state.topic.length; index++) {
        const el = state.topic[index];
        const {type, uAnswer, id} = el;
        const curRAnswer = rAnswer[id];
        const curOption = state.topic[index].option;
        const result = mark(curRAnswer, curOption, type, uAnswer).toString()
        if (result === '2')
          commit(MUTATIONS.SET_RIGHT_ANSWER, {index, rAnswer: getRightAnswer(curRAnswer, curOption, type)})
        commit(MUTATIONS.MARK_ANSWER, {index, result})
      }
      //上传答案
      const {total, remainder, score} = getters.getScoreInfo(ID);
      const {subName, queBankName} = getters.getQueBankInfo(ID);
      const {topicToal, rightCount, jianda} = state.topic.reduce((obj, item) => {
        const {id, uAnswer, type, result} = item
        if (type === '2' && uAnswer)
          obj.jianda.push({id, uAnswer})
        else {
          obj.topicToal++;
          result === '1' && obj.rightCount++
        }
        return obj;
      }, {topicToal: 0, rightCount: 0, jianda: []})
      await axios.post('hand', {
        total,
        remainder,
        score,
        id: ID,
        subName,
        queBankName,
        topicToal,
        rightCount,
        scoreRate: (score / total * 100).toFixed(2),
        jianda,
        topic: state.topic,
        time: state.answerTime
      }).then(({data: {msg}}) => {
        Notification.success({
          title: 'Tip',
          message: msg,
          duration: 1000
        })
      }).catch(console.log)
      resolve()
    })
  },
  markJDAnswer({commit, state}, answer) {
    const {topic} = state
    const JD_Id = topic.map((item) => item.type === '2' ? item.id : -1);
    answer.map(item => {
      const {TM_ID, IS_MARK, T_ANSWER} = item
      let index = JD_Id.indexOf(TM_ID)
      if (IS_MARK === '1') {
        commit(MUTATIONS.SET_RIGHT_ANSWER, {index, rAnswer: T_ANSWER})
        commit(MUTATIONS.MARK_ANSWER, {index, result: '4'})
      }
    })
  }
}

function mark(curRAnswer, curOption, type, uAnswer) {
  //0未做 1正确 2错误 3待定
  //未做
  if (!uAnswer.length) return 0
  //简答题 待定
  if (type === '2' || !curRAnswer) return 3;
  //单选
  if (type === '0')
    return curRAnswer[0] === curOption[uAnswer[0]].id ? 1 : 2;
  //填空 判断
  if (/[34]/.test(type)) return curRAnswer[0] === uAnswer ? 1 : 2
  //多选
  if (type === '1' && curRAnswer.length === uAnswer.length) {
    let result = uAnswer.map(answerIndex => curRAnswer.includes(curOption[answerIndex].id))
    return result.includes(false) ? 2 : 1
  } else return 2
}

function getRightAnswer(answer, option, type) {
  if (/[24]/.test(type)) return answer[0];
  if (type === '3') return answer[0] === '1' ? '正确' : '错误'
  let oId = Array.isArray(option) && option.map(item => item.id)
  return answer.map(item => String.fromCodePoint(oId.indexOf(item) + 65)).sort().join('-')
}

export default {
  state,
  actions,
  getters,
  mutations
}
